package com.itheima.a03.模版方法模式;

import java.util.ArrayList;
import java.util.List;
/*
* 下面的这种设计模式就是对模版方法模式的运用
* 比如在getBean()方法里面，有一些固定不变的，但是哪些会变化的部分，也就是你
* 刚开始设计时，不能确定的部分，你可以抽象成接口，在接口里面定义抽象方法，然后
* 在合适的时机去调用这些抽象方法，这种设计的套路就是模版方法。
* */
public class TestMethodTemplate02 {

    public static void main(String[] args) {
        MyBeanFactory beanFactory = new MyBeanFactory();
        /*给自定义的beanFactory添加后处理器进行解析*/
        beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
            @Override
            public void inject(Object bean) {
                System.out.println("解析 @Autowired");
            }
        });
        beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
            @Override
            public void inject(Object bean) {
                System.out.println("解析 @Resource");
            }
        });
        beanFactory.getBean();
    }

    // 模板方法  Template Method Pattern
    static class MyBeanFactory {
        public Object getBean() {
            Object bean = new Object();
            System.out.println("构造 " + bean);
            System.out.println("依赖注入 " + bean); // @Autowired, @Resource
            for (BeanPostProcessor processor : processors) {
                /*把bean传入进去，方便进行扩展*/
                processor.inject(bean);
            }
            System.out.println("初始化 " + bean);
            return bean;
        }

        /*创建一个后处理器集合*/
        private List<BeanPostProcessor> processors = new ArrayList<>();
        /*并向集合里面添加一个后处理器*/
        public void addBeanPostProcessor(BeanPostProcessor processor) {
            processors.add(processor);
        }

    }

    static interface BeanPostProcessor {
        /*对依赖注入阶段的扩展，实现下面的方法就可以对其进行扩展了*/
        public void inject(Object bean);
    }

}
